package com.gxa.community.admin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gxa.community.admin.mapper.KillGoodsOperateVoMapper;
import com.gxa.community.admin.mapper.OperateKillSpellGoodsMapper;
import com.gxa.community.admin.mapper.OperateKillSpellMapper;
import com.gxa.community.admin.service.OperateKillSpellGoodsService;
import com.gxa.community.admin.service.OperateKillSpellService;
import com.gxa.community.admin.util.CalendarUtils;
import com.gxa.community.core.pojo.bo.SecAddGoodBo;
import com.gxa.community.core.pojo.bo.SecEditGoodsBo;
import com.gxa.community.core.pojo.domain.OperateKillSpell;
import com.gxa.community.core.pojo.domain.OperateKillSpellGoods;
import com.gxa.community.core.pojo.dto.PreEditDto;
import com.gxa.community.core.pojo.dto.SecKillDto;
import com.gxa.community.core.pojo.dto.SeckillQueryDto;
import com.gxa.community.core.pojo.vo.EditkillVo;
import com.gxa.community.core.pojo.vo.KillGoodsOperateVo;
import com.gxa.community.core.pojo.vo.SeckillAddVo;
import com.gxa.community.core.utils.R;
import io.swagger.models.auth.In;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.core.JmsMessagingTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 秒杀信息表 服务实现类
 * </p>
 *
 * @author XYJ
 * @since 2022-07-18
 */
@Service
@Slf4j
public class OperateKillSpellServiceImpl extends ServiceImpl<OperateKillSpellMapper, OperateKillSpell> implements OperateKillSpellService {
    @Autowired
    private OperateKillSpellGoodsMapper secKillGoodsMapper;
    @Autowired
    private OperateKillSpellMapper secKillMapper;
    @Autowired
    private OperateKillSpellGoodsService secKillGoodsService;
    @Autowired
    private OperateKillSpellServiceImpl operateKillSpellService;
    @Autowired
    private KillGoodsOperateVoMapper killGoodsOperateVoMapper;
    @Autowired
    private JmsMessagingTemplate jmsMessagingTemplate;
    public static final String GOODSDEL = "GoodsDel:";

    @Override
    @Transactional
    public R SelectAllSecKill(Integer type) {
//        List<OperateKillSpell> SecKill = this.list();
        List<OperateKillSpell> SecKill = secKillMapper.selectAll(type);
        List seckillDtos = new ArrayList();
        for (OperateKillSpell operateKillSpell : SecKill) {
            SecKillDto secKillDto = new SecKillDto();
            secKillDto.setId(operateKillSpell.getId());
            secKillDto.setAboutNum(secKillGoodsMapper.selectCount(operateKillSpell.getKillId()));
            secKillDto.setName(operateKillSpell.getName());
            secKillDto.setKillId(operateKillSpell.getKillId());
            secKillDto.setTimeStart(operateKillSpell.getStartTime());
            secKillDto.setTimeEnd(operateKillSpell.getEndTime());
            secKillDto.setUplineState(operateKillSpell.getStatus());
            seckillDtos.add(secKillDto);
        }
        System.err.println(seckillDtos);
        return R.ok().put("data", seckillDtos);
    }

    @Override
    @Transactional
    public R AddSecKill(SeckillAddVo seckillAddVo, Integer type) {
        System.err.println(seckillAddVo);
        /*添加秒杀先去数据库里 判断进件的秒杀开始时间是否大于上一个秒杀的结束时间 是的话
        则可以新建，不是的话则返回信息 同一时间段内不能有多个秒杀活动
        */
        Long timeStart = seckillAddVo.getTimeStart();//新建的秒杀开始时间
        //获取数据库里的所有该活动
        QueryWrapper<OperateKillSpell> wrapper = new QueryWrapper<>();
        wrapper.eq("type",type);
        List<OperateKillSpell> operateKillSpells = secKillMapper.selectList(wrapper);
        System.err.println(operateKillSpells);
        for (OperateKillSpell operateKillSpell : operateKillSpells) {
                if (timeStart<operateKillSpell.getEndTime())
                    return R.error("新建活动的开始时间不能小于已有活动的结束时间（一个时间段内只能有一个活动）");
        }
        //获取新建的秒杀的结束时间
        Long timeEnd = seckillAddVo.getTimeEnd();
        //将新建秒杀的开始时间和结束时间的时间戳转化为时间
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        Long aLong = Long.valueOf(timeStart);
        String format = sdf.format(new Date(aLong * 1000L));
        Long aLong1 = Long.valueOf(timeEnd);
        String format1 = sdf.format(new Date(aLong1 * 1000L));
        if (!format.equals(format1)){return R.error("秒杀活动不可跨天");}

        OperateKillSpell secKill = new OperateKillSpell();
        OperateKillSpellGoods secKillGoods = new OperateKillSpellGoods();
        secKill.setName(seckillAddVo.getName());
        secKill.setStartTime(seckillAddVo.getTimeStart());
        secKill.setEndTime(seckillAddVo.getTimeEnd());
        secKill.setStatus(seckillAddVo.getStatus());
        secKill.setTime(seckillAddVo.getTime());
        secKill.setKillId(seckillAddVo.getKillId());
        secKill.setType(type);
        //删除前前台redis删除
//            String message = "活动改变请删除redis";
        jmsMessagingTemplate.convertAndSend(GOODSDEL,new ArrayList<>());
        boolean save = this.save(secKill);
        List<SecAddGoodBo> secAddGoodBo = seckillAddVo.getSecAddGoodBo();
        for (SecAddGoodBo addGoodBo : secAddGoodBo) {
            secKillGoods.setGoodsName(addGoodBo.getGoodsName());
            secKillGoods.setGoodsNo(addGoodBo.getGoodsNo());
            secKillGoods.setKillId(seckillAddVo.getKillId());
            secKillGoods.setLastnum(addGoodBo.getLastnum());
            secKillGoods.setPrice(addGoodBo.getSeckillPrice());
            secKillGoods.setNum(addGoodBo.getNum());
            secKillGoods.setSort(addGoodBo.getSort());
           secKillGoodsService.save(secKillGoods);
        }
        if (save){
            return R.ok("创建成功");
        }
         return R.error("创建失败");
    }

    @Override
    @Transactional
    public R delSekill(String  Killid) {
        System.err.println("==================================================="+Killid);
        OperateKillSpell operateKillSpell = secKillMapper.querByKillId(Killid);
        System.err.println(operateKillSpell);
        if (operateKillSpell!=null){
            Integer status = operateKillSpell.getStatus();
            if(status==1){
                //删除前前台redis删除
//            String message = "活动改变请删除redis";
                jmsMessagingTemplate.convertAndSend(GOODSDEL,new ArrayList<>());
                Integer i = secKillMapper.delKillId(Killid);
                Integer i2 = secKillGoodsMapper.delByKillId(Killid);
                if(i>0||i2>0){
                    return R.ok("删除成功");
                }else return R.error("删除失败");
            }else
                return R.error(301,"只能删除下线状态的秒杀商品");
    }
        return R.error(501,"删除失败请检查秒杀id是否有误") ;
        }

    @Override
    @Transactional
    public R editSeckill(EditkillVo editkillVo,Integer type) {
        OperateKillSpell operateKillSpell = secKillMapper.querByKillId(editkillVo.getKillId());
        Integer status = operateKillSpell.getStatus();
        if (status==1){
            //先进行删除
            int i = secKillMapper.delKillId(editkillVo.getKillId());
            System.err.println("删除条数为"+i);
            //开始添加
            OperateKillSpell secKill = new OperateKillSpell();
//            将值set进去
            secKill.setName(editkillVo.getName());
            secKill.setStartTime(editkillVo.getTimeStart());
            secKill.setEndTime(editkillVo.getTimeEnd());
            secKill.setStatus(editkillVo.getStatus());
            //获取之前的秒杀时间点
            Long times = operateKillSpell.getTime();
            System.err.println(times);
            secKill.setTime(times);
            secKill.setKillId(editkillVo.getKillId());
            secKill.setType(1);
            //删除前前台redis删除
//            String message = "活动改变请删除redis";
            jmsMessagingTemplate.convertAndSend(GOODSDEL,new ArrayList<>());
            boolean save = this.save(secKill);

            //对秒杀商品表进行操作
            Integer integer = secKillGoodsMapper.delByGoods(editkillVo.getKillId());
//            System.err.println("删除成功"+integer);
            List<SecAddGoodBo> secAddGoodBo = editkillVo.getSecAddGoodBo();
            for (SecAddGoodBo addGoodBo : secAddGoodBo) {
                OperateKillSpellGoods secKillGoods = new OperateKillSpellGoods();
                //删除后开始添加
                System.err.println("开始进行添加");
                secKillGoods.setGoodsName(addGoodBo.getGoodsName());
                secKillGoods.setGoodsNo(addGoodBo.getGoodsNo());
                secKillGoods.setKillId(editkillVo.getKillId());
                secKillGoods.setLastnum(addGoodBo.getLastnum());
                secKillGoods.setPrice(addGoodBo.getSeckillPrice());
                secKillGoods.setNum(addGoodBo.getNum());
                secKillGoods.setSort(addGoodBo.getSort());
                secKillGoodsService.save(secKillGoods);
            }
            if (save){
                return R.ok("修改秒杀成功");
            }
            return R.error("修改失败");
        }
        return R.error(302,"只有未上线的秒杀可进行修改");
    }

    @Override
    @Transactional
    public R preEditSeckill(String killId) {
        LambdaQueryWrapper<OperateKillSpell> killlambda = null;
        killlambda = Wrappers.lambdaQuery(OperateKillSpell.class);
        killlambda.eq(OperateKillSpell::getKillId,killId);
        OperateKillSpell operateKillSpell = this.getOne(killlambda);
        System.err.println(operateKillSpell);
        if (operateKillSpell!=null){
        //将查出来的数据set进Editvo
        PreEditDto preEditDto = new PreEditDto();
        preEditDto.setKillId(operateKillSpell.getKillId());
        preEditDto.setName(operateKillSpell.getName());
        preEditDto.setStatus(operateKillSpell.getStatus());
        preEditDto.setTimeEnd(operateKillSpell.getEndTime());
        preEditDto.setTimeStart(operateKillSpell.getStartTime());
        //通过kiiId将商品查出来
        List<OperateKillSpellGoods> operateKillSpellGoods = secKillGoodsMapper.queryListBykillId(killId);
        //循环便利将查出来的商品存在Editvo中
        List<SecEditGoodsBo> editGoodsBos = new ArrayList<>();
        for (OperateKillSpellGoods operateKillSpellGood : operateKillSpellGoods) {
            SecEditGoodsBo secEditGoodsBo = new SecEditGoodsBo();
            secEditGoodsBo.setGoodsName(operateKillSpellGood.getGoodsName());//商品名字
            Integer goodsNo = operateKillSpellGood.getGoodsNo();
            secEditGoodsBo.setGoodsNo(goodsNo);//商品编号
            secEditGoodsBo.setLastnum(operateKillSpellGood.getLastnum());//剩余价格
            secEditGoodsBo.setSeckillPrice(operateKillSpellGood.getPrice());//秒杀价格
            secEditGoodsBo.setNum(operateKillSpellGood.getNum());//秒杀数量
            secEditGoodsBo.setSort(operateKillSpellGood.getSort());//排序
            //根据商品编号来查询商品原价和售价
            secEditGoodsBo.setOriginalPrice(secKillGoodsMapper.queryfirstPrice(goodsNo));//原价
            secEditGoodsBo.setActualPrice(secKillGoodsMapper.querypayPrice(goodsNo));//售价
            //将商品添加到集合中去
            editGoodsBos.add(secEditGoodsBo);
        }
        preEditDto.setSecEditGoodsBo(editGoodsBos);
        System.err.println(preEditDto);
        return R.ok().put("data",preEditDto);
        }
        return R.error(501,"没有该秒杀信息，请检查秒杀编号是否有误");
    }

    @Override
    public R queryText(String name, Integer activeStatus, Integer status, Long startTime, Long endTime,Integer type) {
        System.out.println(name+"===="+activeStatus+"====="+status+"======"+startTime+"======"+endTime);
        if (name.length()==0)name=null;
        System.out.println(name+"===="+activeStatus+"====="+status+"======"+startTime+"======"+endTime);
        if((startTime==null&&endTime!=null)||(startTime!=null&&endTime==null))return R.error(505,"startTime和endTime不能单独一个为null");
        //获取当前时间戳
        long time = new Date().getTime();
        List<SecKillDto> secKillDtos = secKillMapper.queryText(name, activeStatus, time, status, startTime, endTime,type);
        List<SecKillDto> secKillDto1s = new ArrayList<>();
        for (SecKillDto secKillDto : secKillDtos){
            SecKillDto secKillDto1 = new SecKillDto();
            secKillDto1.setKillId(secKillDto.getKillId());
            secKillDto1.setTimeEnd(secKillDto.getTimeEnd());
            secKillDto1.setTimeStart(secKillDto.getTimeStart());
            secKillDto1.setName(secKillDto.getName());
            secKillDto1.setId(secKillDto.getId());
            secKillDto1.setUplineState(secKillDto.getUplineState());
            secKillDto1.setAboutNum(secKillGoodsMapper.selectCount(secKillDto.getKillId()));
            secKillDto1s.add(secKillDto1);
        }
        return R.ok().put("data",secKillDto1s);
    }

    /**
     * 远程通信
     * 获取首页最近的秒杀时间
     * 结束时间大于当前时间,并且开始时间小于当前时间
     * @return
     */
    @Override
    public SeckillQueryDto querykillGoodsOne() {
        QueryWrapper<OperateKillSpell> wrapper = new QueryWrapper<>();
        wrapper.eq("status",0);  //状态为0的
        wrapper.eq("type",1);//活动为秒杀
        wrapper.between("start_time", CalendarUtils.today(),CalendarUtils.todaytail());
        List<OperateKillSpell> list = operateKillSpellService.list(wrapper);
        if (list.size()==0||null==list){
            return null;
        }
        /**
         * 把数据库里的时间拿出来做判断
         * 查找最近的秒杀活动
         */
        List<Integer> list1 = new ArrayList<>();
        List<Integer> list2 = new ArrayList<>();
        SimpleDateFormat dateFormat = new SimpleDateFormat("HH");
        int i2 = Integer.valueOf(dateFormat.format(CalendarUtils.now())).intValue();
        log.info("当前的时间是:{}",i2);
        for (OperateKillSpell spell : list) {
            int i1 = Integer.valueOf(dateFormat.format(spell.getStartTime())).intValue();
            if (i1>=i2){
                //放之后的秒杀信息
                list1.add(i1);
            }else {
                //放之前的秒杀信息
                list2.add(i1);
            }
        }
        int[] a = null;
        int t = 0;//只有 = 0 才会拿之后的数据
        int ij = 0;
        //判断如果之后没有秒杀活动就那拿之前的活动
        if (list1.size()==0||null==list1){
            a = new int[list2.size()];
            log.info("首页:没有最新秒杀进入,查找以往秒杀");
            t+=1;  //t加1   切换成那之前的
            if (list2.size()==0||null==list2){
                log.info("首页:没有以往秒杀");
                //如果之前也没有就返回null
                return null;
            }else {
                for (Integer i : list2) {
                    a[ij] = i;
                    ij++;
                }
            }
        }else {
            log.info("首页:有新的秒杀");
            a = new int[list1.size()];
            for (Integer i : list1) {
                a[ij] = i;
                ij++;
            }
        }
        log.info("排序前========{}",a);
        /**
         * 冒泡排序
         * 算出距离最近的时间的是多少
         */
        int temp = 0;
        for(int i=0;i<a.length-1;i++){
            for(int j=0;j<a.length-1-i;j++) {
                if (a[j] > a[j + 1]) {
                    temp = a[j];
                    a[j] = a[j+1];
                    a[j+1] = temp;
                }
            }
        }
        log.info("排序后========{}",a);
        Integer timess ;
        if (t==0){
            timess = a[0];//之后秒杀的商品
        }else {
            timess = a[a.length-1];//之前的秒杀的商品
        }
        log.info("首页:去数据库查{}时间的秒杀数据",timess);
        SeckillQueryDto seckillQueryDto = new SeckillQueryDto();
        QueryWrapper<OperateKillSpell> owrappere = new QueryWrapper<>();
        owrappere.eq("status",0);  //状态为0的
        owrappere.eq("type",1);//活动为秒杀
        owrappere.eq("start_time",CalendarUtils.setToday(timess));
        OperateKillSpell one = operateKillSpellService.getOne(owrappere);
        QueryWrapper <KillGoodsOperateVo> goodsQueryWrapper = new QueryWrapper<>();
        goodsQueryWrapper.eq("kill_id",one.getKillId());
        List<KillGoodsOperateVo> goods = killGoodsOperateVoMapper.selectList(goodsQueryWrapper);
        seckillQueryDto.setOperateKillSpellGoods(goods);
        seckillQueryDto.setTime(dateFormat.format(one.getStartTime()));
        seckillQueryDto.setName(one.getName());
        seckillQueryDto.setEndTime(one.getEndTime());
        seckillQueryDto.setStartTime(one.getStartTime());
        return seckillQueryDto;
    }

    /**
     * 远程通信
     * 获取所有的秒杀信息
     * @return seckillQueryDtoList 所有秒杀商品的信息
     */
    @Override
    public List<SeckillQueryDto> querykillGoodsList() {
        QueryWrapper<OperateKillSpell> wrapper = new QueryWrapper<>();
        wrapper.eq("status",0);  //状态为0的
        wrapper.eq("type",1);//活动为秒杀
        wrapper.between("start_time", CalendarUtils.today(),CalendarUtils.todaytail());
        List<OperateKillSpell> list = operateKillSpellService.list(wrapper);
        if (list.size()==0||null==list){
            return null;
        }
        SimpleDateFormat dateFormat = new SimpleDateFormat("HH");
        List<SeckillQueryDto> seckillQueryDtoList = new ArrayList<>();
        QueryWrapper <KillGoodsOperateVo> goodsQueryWrapper = new QueryWrapper<>();
        for (OperateKillSpell spell : list) {
            SeckillQueryDto dto = new SeckillQueryDto();
            goodsQueryWrapper.eq("kill_id",spell.getKillId());
            List<KillGoodsOperateVo> goods = killGoodsOperateVoMapper.selectList(goodsQueryWrapper);
            dto.setOperateKillSpellGoods(goods);
            dto.setName(spell.getName());
            dto.setStartTime(spell.getStartTime());
            dto.setEndTime(spell.getEndTime());
            dto.setTime(dateFormat.format(spell.getStartTime()));
            seckillQueryDtoList.add(dto);
        }
        return seckillQueryDtoList;
    }

    /**
     * 获取今日拼团信息
     * @return SeckillQueryDto
     */
    @Override
    public List<SeckillQueryDto> gropuQueryList() {
        QueryWrapper<OperateKillSpell> wrapper = new QueryWrapper<>();
        wrapper.eq("status",0);  //状态为0的
        wrapper.eq("type",2);//活动为2拼团
        wrapper.between("start_time", CalendarUtils.today(),CalendarUtils.todaytail());//获取当日一整天的活动信息
        List<OperateKillSpell> list = operateKillSpellService.list(wrapper);
        if (list.size()==0||null==list){
            return null;
        }
        List<SeckillQueryDto> seckillQueryDtoList = new ArrayList<>();
        SimpleDateFormat dateFormat = new SimpleDateFormat("HH");
        for (OperateKillSpell spell : list) {
            SeckillQueryDto dto = new SeckillQueryDto();
            QueryWrapper <KillGoodsOperateVo> goodsQueryWrapper = new QueryWrapper<>();
            goodsQueryWrapper.eq("kill_id",spell.getKillId());
            List<KillGoodsOperateVo> goods = killGoodsOperateVoMapper.selectList(goodsQueryWrapper);
            dto.setOperateKillSpellGoods(goods);
            dto.setName(spell.getName());
            dto.setStartTime(spell.getStartTime());
            dto.setEndTime(spell.getEndTime());
            dto.setTime(dateFormat.format(spell.getStartTime()));
            seckillQueryDtoList.add(dto);
        }
        return seckillQueryDtoList;
    }
}
